/**
 * @file 功能权限
 * @date 2025/11/09 00:04:37
 * @author lyqjob@yeah.net
 */

import { memo, useEffect, forwardRef, useCallback, useMemo, useRef, useImperativeHandle } from 'react';
import { Spin, Row, Col, Tree, Collapse, Checkbox, Flex, Form } from 'antd';
import { CaretRightOutlined } from '@ant-design/icons';

const FunctionPermission = forwardRef((props, ref) => {


    const { is_edit, treeData, permissionData, checkedKeys, onChange, rolePermissions } = props;

    // const [loading, setLoading] = useState(true);

    const [form] = Form.useForm();

    const lastFormValuesRef = useRef(null);
    useEffect(() => {
        if (rolePermissions?.length) {
            const moduleCodes = {};
            rolePermissions.forEach(item => {
                const mc = item.module_code || 'default';
                if (!Object.prototype.hasOwnProperty.call(moduleCodes, mc)) {
                    moduleCodes[mc] = [item.id];
                } else {
                    moduleCodes[mc].push(item.id);
                }
            });
            const serialized = JSON.stringify(moduleCodes);
            if (serialized !== lastFormValuesRef.current) {
                form.setFieldsValue(moduleCodes);
                lastFormValuesRef.current = serialized;
            }
        }
    }, [rolePermissions, form]);


    // 已选择的模块分组键 - 使用 useMemo 优化
    const selecctedGroupKeys = useMemo(() => {
        if (rolePermissions?.length) {
            const moduleCodes = {};
            rolePermissions.forEach(item => {
                const mc = item.module_code || 'default';
                if (!Object.prototype.hasOwnProperty.call(moduleCodes, mc)) {
                    moduleCodes[mc] = [item.id];
                } else {
                    moduleCodes[mc].push(item.id);
                }
            });
            return Object.keys(moduleCodes);
        }
        return [];
    }, [rolePermissions]);


    // 数据转换 - 按module_code分组构建树形结构 - 使用 useMemo 优化
    const convertPermissionTreeData = useMemo(() => {
        return (permissions, isEdit, rolePermissions) => {
            if (!permissions?.length) { return []; }

            // 获取当前角色已绑定的权限ID列表
            const boundPermissionIds = rolePermissions.map(p => p.id);

            // 按module_code分组
            const moduleMap = new Map();

            permissions.forEach(permission => {
                const moduleCode = permission.module_code || 'default';
                if (!moduleMap.has(moduleCode)) {
                    moduleMap.set(moduleCode, {
                        module_code: moduleCode,
                        module_name: permission.module_name || moduleCode,
                        permissions: []
                    });
                }
                moduleMap.get(moduleCode).permissions.push(permission);
            });

            // 转换为Collapse组件需要的格式
            return Array.from(moduleMap.values()).map(group => ({
                key: group.module_code,
                label:
                    <div>
                        <Form.Item noStyle shouldUpdate={(prev, cur) => prev[group.module_code] !== cur[group.module_code]}>
                            {() => {
                                const selected = form.getFieldValue(group.module_code) || [];
                                const allIds = group.permissions.map(p => p.id);
                                const checkedAll = selected.length > 0 && selected.length === allIds.length;
                                const indeterminate = selected.length > 0 && selected.length < allIds.length;
                                return isEdit ? (
                                    <Checkbox
                                        checked={checkedAll}
                                        indeterminate={indeterminate}
                                        onChange={(e) => onToggleGroup(group.module_code, allIds, e.target.checked)}
                                        style={{ width: '20%' }}
                                        key={group.module_code + '-' + group.module_name}
                                    >
                                        {group.module_name}
                                    </Checkbox>
                                ) :
                                    (
                                        <span style={{
                                            color: checkedAll ? '#1890ff' : 'inherit',
                                            fontWeight: checkedAll ? 'bold' : 'normal'
                                        }}>
                                            {group.module_name}
                                        </span>
                                    )



                            }}
                        </Form.Item>
                    </div>
                ,
                collapsible: 'icon',
                children: (
                    <div style={{ width: '100%' }}>
                        {isEdit ? (
                            <Form.Item
                                style={{ width: '100%', marginRight: 0 }}
                                name={group.module_code}
                            >
                                <Checkbox.Group style={{ width: '100%' }}>
                                    <Flex align="start" wrap="wrap" style={{ width: '100%' }}>
                                        {
                                            group.permissions.map(permission => (
                                                <Checkbox
                                                    value={permission.id}
                                                    style={{ width: '20%' }}
                                                    key={permission.id}
                                                >
                                                    <span style={{
                                                        color: boundPermissionIds.includes(permission.id) ? '#1890ff' : 'inherit',
                                                        fontWeight: boundPermissionIds.includes(permission.id) ? 'bold' : 'normal'
                                                    }}>
                                                        {permission.permission_name}
                                                    </span>
                                                </Checkbox>
                                            ))
                                        }
                                    </Flex>
                                </Checkbox.Group>
                            </Form.Item>
                        ) : (
                            <Flex align="start" wrap="wrap" style={{ width: '100%' }}>
                                {
                                    group.permissions.map(permission => (
                                        <span
                                            style={{
                                                width: '24%',
                                                color: boundPermissionIds.includes(permission.id) ? '#1890ff' : '#666',
                                                fontWeight: boundPermissionIds.includes(permission.id) ? 'bold' : 'normal'
                                            }}
                                            key={permission.id}
                                        >
                                            {boundPermissionIds.includes(permission.id) ? '✓ ' : ''}
                                            {permission.permission_name}
                                        </span>
                                    ))
                                }
                            </Flex>
                        )}
                    </div>
                ),
                style: {
                    marginBottom: '8px'
                }
            }));
        };
    }, []);

    // 使用 useMemo 缓存权限树数据，避免不必要的重新计算
    const permissionTreeData = useMemo(() => {
        if (permissionData && permissionData.length > 0) {
            return convertPermissionTreeData(permissionData, is_edit, rolePermissions);
        }
        return [];
    }, [permissionData, is_edit, rolePermissions, convertPermissionTreeData]);

    // 根据权限数据计算模块编码列表，避免额外状态更新导致的二次渲染
    const moduleCodes = useMemo(() => {
        if (!permissionData || permissionData.length === 0) { return []; }
        const moduleSet = new Set();
        for (const p of permissionData) {
            moduleSet.add(p.module_code || 'default');
        }
        return Array.from(moduleSet);
    }, [permissionData]);


    // 暴露方法给父组件
    useImperativeHandle(ref, () => ({
        getData: () => {
            return getPermissionData();
        },
        validateForm: () => {
            return form.validateFields();
        },
        resetForm: () => {
            form.resetFields();
        },
        setFormData: (data) => {
            form.setFieldsValue(data);
        }
    }));


    // 获取权限选中数据
    const getPermissionData = useCallback(() => {
        const permissionData = [];
        moduleCodes.forEach(module_code => {
            const module_code_values = form.getFieldValue(module_code);
            // 安全处理：检查是否为数组且不为空
            if (Array.isArray(module_code_values) && module_code_values.length > 0) {
                permissionData.push(...module_code_values);
            }
        });
        // 去重并返回
        return [...new Set(permissionData)];
    }, [moduleCodes, form]);

    // 模块复选框点击事件 - 处理全选/取消全选
    const onToggleGroup = useCallback((moduleCode, allIds, checked) => {
        const nextValues = checked ? [...allIds] : [];
        form.setFieldsValue({ [moduleCode]: nextValues });
    }, [form]);


    // 菜单树选中事件 - 处理复选框选中/取消(状态提升)
    const onCheck = useCallback((checkedKeysValue) => {
        if (typeof onChange === 'function') {
            onChange('function', checkedKeysValue);
        }
    }, [onChange]);



    return (
        <Row style={{ height: '100%' }} >
            <Col span={6} style={{ height: '100%', overflowY: 'auto', padding: 15 }}>
                {treeData && treeData.length > 0 ? <Tree
                    checkable={is_edit}
                    treeData={treeData}
                    autoExpandParent={true}
                    defaultExpandAll={true}
                    showLine={true}
                    onCheck={onCheck}
                    checkedKeys={checkedKeys}
                // showIcon
                // onSelect={onSelect}
                /> :
                    <Spin spinning={treeData === null || treeData === undefined} title="菜单数据加载中..." />
                }
            </Col>
            <Col span={18} style={{ height: '100%', overflowY: 'auto', padding: 10 }}>
                <Form
                    name="function_permission_form"
                    form={form}
                    initialValues={{}}
                    colon={!is_edit}
                    autoComplete="off"
                    layout="inline"
                    style={{ width: '100%' }}
                >

                    {
                        permissionTreeData && moduleCodes.length > 0 ?
                            <Collapse
                                bordered={true}
                                defaultActiveKey={moduleCodes}
                                // defaultActiveKey={access_type === 'view'?[...module_codes]:[]}
                                expandIcon={({ isActive }) => <CaretRightOutlined rotate={isActive ? 90 : 0} />}
                                style={{ width: '100%', backgroundColor: '#fff' }}
                                items={permissionTreeData}
                            /> :
                            <Spin spinning={permissionTreeData === null || permissionTreeData === undefined} title="权限数据加载中..." />
                    }
                </Form>
            </Col>
        </Row>
    )
})

const areArrayEqual = (a = [], b = []) => {
    if (a === b) { return true; }
    if (a.length !== b.length) { return false; }
    for (let i = 0; i < a.length; i++) {
        if (a[i] !== b[i]) { return false; }
    }
    return true;
};

const areEqual = (prev, next) => {
    if (prev.is_edit !== next.is_edit) { return false; }
    if (!areArrayEqual(prev.checkedKeys, next.checkedKeys)) { return false; }
    if (!areArrayEqual(prev.treeData, next.treeData)) { return false; }
    if (!areArrayEqual(prev.permissionData, next.permissionData)) { return false; }
    const rpPrev = (prev.rolePermissions || []).map(p => p.id).join(',');
    const rpNext = (next.rolePermissions || []).map(p => p.id).join(',');
    if (rpPrev !== rpNext) { return false; }
    if (prev.onChange !== next.onChange) { return false; }
    return true;
};

export default memo(FunctionPermission, areEqual);